﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Shapes;
using VNet.VisiSuite.VisiBoard.ViewModels;

namespace VNet.VisiSuite.VisiBoard.Common.Helpers
{
    public static class StyleBinder
    {
        public static readonly DependencyProperty StyleBinderHelperProperty = DependencyProperty.RegisterAttached("StyleBinderHelper", typeof(StyleBinderHelper), typeof(StyleBinder), new PropertyMetadata(null, (o, e) => StyleBinderHelperChanged(o, e)));
        public static readonly DependencyProperty StyleBinderContentProperty = DependencyProperty.RegisterAttached("StyleBinderContent", typeof(FrameworkElement), typeof(StyleBinder), new PropertyMetadata(null, (o, e) => StyleBinderContentChanged(o, e)));
        public static readonly DependencyProperty StyleBinderContextProperty = DependencyProperty.RegisterAttached("StyleBinderContext", typeof(object), typeof(StyleBinder), new PropertyMetadata(null, (o, e) => StyleBinderContextChanged(o, e)));

        private static void StyleBinderHelperChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement element = o as FrameworkElement;
            if (element == null)
            {
                return;
            }

            BindingExpression be = element.GetBindingExpression(StyleBinder.StyleBinderContextProperty);

            if (be == null)
            {
                element.SetBinding(StyleBinderContextProperty, new Binding());
            }

            if (e.NewValue != null)
            {
                ((StyleBinderHelper)e.NewValue).PushContent(element);
            }
        }

        public static void SetStyleBinderHelper(DependencyObject target, StyleBinderHelper value)
        {
            target.SetValue(StyleBinderHelperProperty, value);
        }

        public static StyleBinderHelper GetStyleBinderHelper(DependencyObject target)
        {
            return (StyleBinderHelper)target.GetValue(StyleBinderHelperProperty);
        }

        private static void StyleBinderContentChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
        }

        public static void SetStyleBinderContent(DependencyObject target, FrameworkElement value)
        {
            target.SetValue(StyleBinderContentProperty, value);
        }

        public static FrameworkElement GetStyleBinderContent(DependencyObject target)
        {
            return (FrameworkElement)target.GetValue(StyleBinderContentProperty);
        }

        private static void StyleBinderContextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement content = StyleBinder.GetStyleBinderContent(o);
            if (content != null)
            {
                content.DataContext = new HelperContext()
                {
                    OuterContext = e.NewValue,
                    Owner = o as FrameworkElement
                };
            }
        }

        public static void SetStyleBinderContext(DependencyObject target, object value)
        {
            target.SetValue(StyleBinderContextProperty, value);
        }

        public static object GetStyleBinderContext(DependencyObject target)
        {
            return target.GetValue(StyleBinderContextProperty);
        }
    }

    public class StyleBinderHelper : FrameworkElement
    {
        internal void PushContent(FrameworkElement element)
        {
            if (Template == null)
                return;

            FrameworkElement content = Template.LoadContent() as FrameworkElement;
            if (content == null)
                return;

            content.DataContext = new HelperContext()
            {
                OuterContext = StyleBinder.GetStyleBinderContext(element),
                Owner = element
            };

            StyleBinder.SetStyleBinderContent(element, content);
        }

        public DataTemplate Template { get; set; }
    }

    public class HelperContext : INotifyPropertyChanged
    {
        private object _outerContext;
        public object OuterContext
        {
            get { return _outerContext; }
            set
            {
                _outerContext = value;
                RaisePropertyChanged("OuterContext");
            }
        }

        private FrameworkElement _owner;
        public FrameworkElement Owner
        {
            get { return _owner; }
            set
            {
                _owner = value;
                RaisePropertyChanged("Owner");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,
                    new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    public class RectangleColorChanger : FrameworkElement
    {
        #region Properties
        public static readonly DependencyProperty RectangleProperty = DependencyProperty.Register("Rectangle", typeof(Rectangle), typeof(RectangleColorChanger), new PropertyMetadata(null, (o, e) => (o as RectangleColorChanger).RectangleChanged(e)));
        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(RectangleColorChanger), new PropertyMetadata(0.0, (o, e) => (o as RectangleColorChanger).ValueChanged(e)));

        public Rectangle Rectangle
        {
            get { return (Rectangle)GetValue(RectangleProperty); }
            set { SetValue(RectangleProperty, value); }
        }

        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        #endregion

        private void ColorChanged(DependencyPropertyChangedEventArgs e)
        {
            UpdateColor();
        }

        private void ValueChanged(DependencyPropertyChangedEventArgs e)
        {
            UpdateColor();
        }

        private void RectangleChanged(DependencyPropertyChangedEventArgs e)
        {
            UpdateColor();
        }

        private void UpdateColor()
        {
            if (Rectangle == null || Rectangle.DataContext.GetType() != typeof(Infragistics.Controls.Charts.DataContext))
                return;


            //Rectangle.Fill = Color;
        }
    }
}
